package com.sm.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sm.tool.entity.dto.SentTicketDTO;
import com.sm.tool.entity.dto.SentTicketsDTO;
import com.sm.tool.entity.po.Tickets_;
import com.sm.tool.entity.po.UserTicket;
import com.sm.tool.entity.po.User_;
import com.sm.tool.entity.request.UserLoginRequest;
import com.sm.tool.entity.request.UserPhoneLoginRequest;
import com.sm.tool.entity.request.UserRegisterRequest;
import com.sm.tool.entity.response.ReturnData;
import com.sm.tool.entity.response.VerificationCode;
import com.sm.tool.enums.NumberEnums;
import com.sm.tool.enums.ResultEnums;
import com.sm.tool.utils.*;
import com.sm.user.feigns.TicketFeignClient;
import com.sm.user.mapper.UserRegLoginMapper;
import com.sm.user.mapper.UserTicketMapper;
import com.sm.user.service.UserRegLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

@Service
@Slf4j
public class UserRegLoginServiceImpl implements UserRegLoginService {

    @Autowired
    private JedisCluster jedisCluster;
    @Autowired
    private UserRegLoginMapper userRegLoginDao;

    private final static int VER_CODE_EXPRICE_TIME = 300;

    private final static int ON_LINE_TIME = 1000 * 60 * 30;

    private final static int ADMIN_ON_LINE_TIME = 1000 * 60 * 60;

    private final static String VER_REG = "ver_reg_";
    private final static String VER_LOG = "ver_log_";

    @Autowired
    private UserTicketMapper userTicketMapper;

    @Autowired
    private TicketFeignClient ticketFeignClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public ReturnData register(UserRegisterRequest userRegisterRequest) {
        /**
         * 检查用户名是否重复
         */
        int countUserName = userRegLoginDao.checkUserName(userRegisterRequest.getUserName());

        if (NumberEnums.ZERO.getNumber() != countUserName) {
            return ReturnData.builder().code(ResultEnums.USERNAME_ALREADY_EXIST.getCode()).msg(ResultEnums.USERNAME_ALREADY_EXIST.getMessage()).build();
        }
        String nickName = userRegisterRequest.getNickName();
        String passWordStr = Base64.getEncoder().encodeToString(userRegisterRequest.getPassWord().getBytes());

        /**
         * 生成用户信息
         */
        User_ user_ = User_.builder()
                .userName(userRegisterRequest.getUserName())
                .nickName(nickName == null ? RandomNameUtil.randomName() : nickName)
                .passWord(passWordStr)
                .userSecret(passWordStr + userRegisterRequest.getUserName())
                .phone(userRegisterRequest.getPhone())
                .state(NumberEnums.ONE.getNumber())
                .balance(new BigDecimal(NumberEnums.TEN.getNumber())).build();

        int sign = userRegLoginDao.insert(user_);

        /**
         * 赠送注册券
         */
        Tickets_ tickets_ = ticketFeignClient.queryLikeTicketCode("25yu1ss6xx6666t");
        if (tickets_ != null) {
            SentTicketDTO sentTicketDTO = SentTicketDTO.builder()
                    .number(NumberEnums.ONE.getNumber())
                    .tickets_(tickets_)
                    .build();
            List<SentTicketDTO> sentTicketDTOList = new ArrayList<>();
            sentTicketDTOList.add(sentTicketDTO);

            SentTicketsDTO sentTickestDTO =
                    SentTicketsDTO.builder()
                            .sentTicketDTOList(sentTicketDTOList)
                            .userId(user_.getId())
                            .build();
            /**
             * 发送到mq
             */
            rocketMQTemplate.syncSend("sm_sent_ticket_topic", sentTickestDTO);
        }
        ReturnData returnData =
                ReturnData.builder()
                        .code(ResultEnums.SUCCESS.getCode())
                        .msg(sign == NumberEnums.ONE.getNumber() ? ResultEnums.SUCCESS.getMessage() : ResultEnums.REGISTER_FAIL.getMessage())
                        .build();
        return returnData;
    }

    @Override
    public ReturnData login(UserLoginRequest userLoginRequest) {
        /**
         * 检查用户是否正常
         */
        User_ user = userRegLoginDao.selectUser(userLoginRequest.getUserName());
        String passWordStr = Base64.getEncoder().encodeToString(userLoginRequest.getPassWord().getBytes());

        if (user != null && passWordStr.equals(user.getPassWord())) {

            if (user.getIsAdmin() == NumberEnums.ONE.getNumber()) {
                //管理员使用jwt token
                String adminToken = JwtUtil.createJWT(String.valueOf(user.getId()));
                jedisCluster.setex(adminToken, ADMIN_ON_LINE_TIME, String.valueOf(user.getId()));
                return ReturnData.builder()
                        .code(ResultEnums.SUCCESS.getCode())
                        .msg(ResultEnums.SUCCESS.getMessage())
                        .Data(adminToken)
                        .build();
            }
            /**
             * 生成token
             */
            String token = UUIDUtil.getUUID();
            String userIdStr = String.valueOf(user.getId());
            jedisCluster.setex(token, ON_LINE_TIME, userIdStr);
            return ReturnData.builder()
                    .code(ResultEnums.SUCCESS.getCode())
                    .msg(ResultEnums.SUCCESS.getMessage())
                    .Data(token)
                    .build();
        }
        return ReturnData.builder()
                .code(ResultEnums.USER_NOT_FOUND.getCode())
                .msg(ResultEnums.USER_NOT_FOUND.getMessage())
                .build();
    }

    /**
     * 获取注册验证码
     *
     * @param phone
     * @return
     */
    @Override
    public ReturnData<VerificationCode> getRegisterVerificationCode(String phone) {
        String vcode = RandomUtil.getCode(NumberEnums.FOUR.getNumber());
        /**
         * 检查该用户五分钟内是否已获取验证码
         */
        String key = VER_REG + phone;
        if (jedisCluster.get(key) != null) {
            return ReturnData.<VerificationCode>builder().code(ResultEnums.VCODE_FIVE.getCode()).msg(ResultEnums.VCODE_FIVE.getMessage()).build();
        }

        if (SMSUtils.sendPhoneVerifyCode(phone, vcode)) {
            jedisCluster.setex(key, VER_CODE_EXPRICE_TIME, vcode);
        }
        return ReturnData.<VerificationCode>builder().Data(VerificationCode.builder().verificationCode(vcode).build()).build();
    }

    /**
     * 用户手机验证🐎登录
     *
     * @param userPhoneLoginRequest
     * @return
     */
    @Override
    public ReturnData phoneLogin(UserPhoneLoginRequest userPhoneLoginRequest) {
        String phone = userPhoneLoginRequest.getPhone();
        String key = VER_LOG + phone;
        String vcode = jedisCluster.get(key);
        if (vcode != null) {
            if (vcode.equals(userPhoneLoginRequest.getVerificationCode())) {
                QueryWrapper<User_> queryWrapper = new QueryWrapper<>();
                queryWrapper
                        .eq("phone", phone).eq("state", NumberEnums.ONE.getNumber());
                User_ user = userRegLoginDao.selectOne(queryWrapper);
                if (user == null) {
                    //用户不存在
                    return ReturnData.builder()
                            .code(ResultEnums.USER_NOT_FOUND.getCode())
                            .msg(ResultEnums.USER_NOT_FOUND.getMessage())
                            .build();
                } else if (user.getIsAdmin() == NumberEnums.ONE.getNumber()) {
                    return ReturnData.builder()
                            .code(ResultEnums.ADMINNOSUPPET.getCode())
                            .msg(ResultEnums.ADMINNOSUPPET.getMessage())
                            .build();
                }

                String token = UUIDUtil.getUUID();
                String userIdStr = String.valueOf(user.getId());
                jedisCluster.setex(token, VER_CODE_EXPRICE_TIME, userIdStr);
                return ReturnData.builder()
                        .code(ResultEnums.SUCCESS.getCode())
                        .msg(ResultEnums.SUCCESS.getMessage())
                        .Data(token)
                        .build();
            } else {
                return ReturnData.builder()
                        .code(ResultEnums.VCODE_ERROR.getCode())
                        .msg(ResultEnums.VCODE_ERROR.getMessage())
                        .build();
            }
        } else {
            return ReturnData.builder()
                    .code(ResultEnums.VCODE_NONENTITY.getCode())
                    .msg(ResultEnums.VCODE_NONENTITY.getMessage())
                    .build();
        }

    }


    /**
     * 获取登录验证码
     *
     * @param phone
     * @return
     */
    @Override
    public ReturnData<VerificationCode> getLoginVerificationCode(String phone) {
        String vcode = RandomUtil.getCode(NumberEnums.FOUR.getNumber());
        /**
         * 检查该用户五分钟内是否已获取验证码
         */
        String key = VER_LOG + phone;
        if (jedisCluster.get(key) != null) {
            return ReturnData.<VerificationCode>builder().code(ResultEnums.VCODE_FIVE.getCode()).msg(ResultEnums.VCODE_FIVE.getMessage()).build();
        }

        if (SMSUtils.sendPhoneVerifyCode(phone, vcode)) {
            jedisCluster.setex(key, VER_CODE_EXPRICE_TIME, vcode);
        }
        return ReturnData.<VerificationCode>builder().Data(VerificationCode.builder().verificationCode(vcode).build()).build();
    }
}
